<?php
/*
+-----------------------------------------------------------------------------+
| $Id: bwsession.class.php 2008-10-16 13:14:11Z Bleakwind $
| System Session
| Copyright (c) 2003-2010 Bleakwind (www.weaverdream.com)
| http://www.weaverdream.com/
| Release under the GNU Lesser General Public License Version 3 (LGPLv3):
|   http://www.gnu.org/licenses/lgpl.html
+-----------------------------------------------------------------------------+
*/

class bwsession {

    // Connection parameters
    var $hostname       = "localhost";
    var $username       = "root";
    var $password       = null;
    var $database       = null;
    var $charset        = "UTF8";
    var $table_session  = "session";

    // session_name
    var $session_name   = "PHPSESSID";
    var $session_id;

    // session life name
    var $lifetime_name  = "lifetime";

    // Session variable
    var $_              = array();

    // db objects
    var $db_session;

    // Other
    var $admin_email     = "root"; // If error,contact who?
    var $halt_on_error   = "jump"; // "yes" (halt with message),
                                   // "no" (halt with no message),
                                   // "report" (go on with message),
                                   // "jump" (go on with no message),

    // Change the save_handler to use the MySQL database
    function bwsession($hostname = "localhost", $username = "root", $password = null, $database = null, $charset = null, $table_session = null)
    {
        if(is_array($hostname)){
            if(!empty($hostname['hostname']))       { $this->hostname       = $hostname['hostname']; }
            if(!empty($hostname['username']))       { $this->username       = $hostname['username']; }
            if(!empty($hostname['password']))       { $this->password       = $hostname['password']; }
            if(!empty($hostname['database']))       { $this->database       = $hostname['database']; }
            if(!empty($hostname['charset']))        { $this->charset        = $hostname['charset']; }
            if(!empty($hostname['table_session']))  { $this->table_session  = $hostname['table_session']; }
        } else {
            if (!empty($hostname))      { $this->hostname       = $hostname; }
            if (!empty($username))      { $this->username       = $username; }
            if (!empty($password))      { $this->password       = $password; }
            if (!empty($database))      { $this->database       = $database; }
            if (!empty($charset))       { $this->charset        = $charset; }
            if (!empty($table_session)) { $this->table_session  = $table_session; }
        }
        $this->db_session = &ADONewConnection(CONFIG_DB_TYPE);
        $this->db_session->NConnect($this->hostname, $this->username, $this->password, $this->database);
        $this->db_session->Execute("SET NAMES '".$this->charset."'");
    }

    function session_name($name = null)
    {
        if (preg_match("/^[a-z0-9_]+$/i",$name) ) {
            $this->session_name = $name;
        }
        session_name($this->session_name);
        return $this->session_name;
    }

    function session_id($id=null, $lifetime = 0, $path = null, $domain = null)
    {
        if (preg_match("/^[a-z0-9_]+$/i",$id) ) {
            setcookie($this->session_name, $id, time() + $lifetime, $path, $domain);
            $this->session_id = $_COOKIE[$this->session_name];
        } else {
            $this->session_id = $_COOKIE[$this->session_name];
            if(empty($this->session_id)){
                $sid_notexists = false;
                while($sid_notexists === false) {
                    $this->session_id = sha1(microtime());
                    $sql = "SELECT sid FROM ".$this->table_session." WHERE sid='".$this->session_id."'";
                    $result = &$this->db_session->Execute($sql);
                    if (!$result) {
                        $this->halt('Query failed : '.$this->db_session->ErrorMsg());
                    } else {
                        if ($result->EOF) {
                            $sid_notexists = true;
                        }
                    }
                }
                setcookie($this->session_name, $this->session_id, time() + $lifetime, $path, $domain);
            }
        }
        return $this->session_id;
    }

    function session_start()
    {
        if (empty($this->session_id)) { $this->session_id(); }
        session_id($this->session_id);
        $this->gc();
        if ( false === $this->read($this->session_id)){
            $sql = "INSERT INTO ".$this->table_session." SET
                        sid     ='".$this->session_id."',
                        expiry  =".$this->return_expiry()."";
            $result = &$this->db_session->Execute($sql);
            if (!$result) {
                $this->halt('Query failed : '.$this->db_session->ErrorMsg());
            }else{
                $this->read($this->session_id);
            }
        }
        return;
    }

    // Write new data to database
    function read($sid)
    {
        $sql = "SELECT * FROM ".$this->table_session." WHERE sid='".$sid."'";
        $result = &$this->db_session->Execute($sql);
        if (!$result) {
            $this->halt('Query failed : '.$this->db_session->ErrorMsg());
            return false;
        } else {
            if (!$result->EOF) {
                $this->_ = $result->fields;
                return true;
            } else {
                return false;
            }
        }
    }

    // Write new data to database
    function set($field, $value=null)
    {
        if (is_array($field)) {
            $str_query = "";
            foreach ($field as $k => $v) {
                $str_query .= $k."='".addslashes($v)."',";
            }
            $str_query = substr($str_query, 0, -1);
        } else {
            $str_query = $field."='".addslashes($value)."'";
        }
        $sql = "UPDATE ".$this->table_session." SET
                    expiry      =".$this->return_expiry().",
                    ".$str_query."
                WHERE sid='".$this->session_id."'";
        $result = &$this->db_session->Execute($sql);
        if (!$result) {
            $this->halt('Query failed : '.$this->db_session->ErrorMsg());
            return false;
        } else {
            return true;
        }
    }

    // Garbage collection, deletes old sessions
    function del($field)
    {
        if (is_array($field)) {
            $str_query = "";
            foreach ($field as $k => $v) {
                $str_query .= $k."=null,";
            }
            $str_query = substr($str_query, 0, -1);
        } else {
            $str_query = $field."=''";
        }
        $sql = "UPDATE ".$this->table_session." SET
                    expiry      =".$this->return_expiry().",
                    ".$str_query."
                WHERE sid='".$this->session_id."'";
        $result = &$this->db_session->Execute($sql);
        if (!$result) {
            $this->halt('Query failed : '.$this->db_session->ErrorMsg());
            return false;
        } else {
            return true;
        }
    }

    // Garbage collection, deletes old sessions
    function gc()
    {
        $sql   = "DELETE FROM " . $this->table_session . " WHERE expiry < " . time();
        $result = &$this->db_session->Execute($sql);
        if (!$result) {
            $this->halt('Query failed : '.$this->db_session->ErrorMsg());
            return false;
        } else {
            return true;
        }
    }

    // Get session's life
    function return_life()
    {
        $maxlifetime    = (int)$this->_[$this->lifetime_name];
        $gc_maxlifetime = (int)ini_get("session.gc_maxlifetime");

        if ($maxlifetime > 0) {
            return $maxlifetime;
        } elseif ($gc_maxlifetime > 0) {
            return $gc_maxlifetime;
        } else {
            return 1440;
        }
    }

    // Get session's life
    function return_expiry()
    {
        $expiry = time() + $this->return_life();
        return $expiry;
    }

    // private: error handling
    function halt($msg)
    {
        $this->error_msg = $msg;
        if ($this->halt_on_error == "yes" || $this->halt_on_error == "report") {
            printf("<div style='font-family:sans-serif;font-size: 11px;'><b>Weaverdream info:</b> SESSION Error</div>\n");
            printf("<div style='width:600px;padding: 3px;background-color:#D6DFF7;border:#1151BF 1px solid;font-family:sans-serif;font-size: 11px;'>\n");
            printf("<b>Page:</b> ".$_SERVER['PHP_SELF']."<br>\n");
            printf("<b>SESSION error:</b> %s <br>\n", $msg);
            printf("</div>\n");
            printf("<div style='font-family:sans-serif;font-size: 11px;'>You can try to <a href='javascript:location.reload()' target='_self'><font color='#1151BF' style='text-decoration:none;'>refresh</font></a> the page, if this doesn't fix the error, please contact <font color='#1151BF'>".$this->admin_email."</font> and report the error message.</div>\n");
        }
        if ( $this->halt_on_error == "yes" ) {
            exit("<div style='font-family:sans-serif;font-size: 11px;'>SESSION halted.</div>\n");
        }elseif( $this->halt_on_error == "no" ){
            exit();
        }
        return $this->error_msg;
    }
}
?>
